package com.example.demo.util;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.HashMap;



public class JsonBody extends HashMap<String, Object> {

    public JsonBody(HashMap<String, Object> readValue) {
        super(readValue);
    }

    public enum StatusCode {
        UNKNOWN_CODE(-1, "unknown_code"),
        SUCCESS(0, "success"),
        ERROR(500, "error"),
        COMMAND(1000, "command");

        private final int code;
        private final String msg;
        StatusCode(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }

        public int code() { return this.code; }
        public String msg() { return this.msg; }

        public static StatusCode valueOf(int code) {
            for (StatusCode c : StatusCode.values()) {
                if (c.code == code) { return c; }
            }
            return null;
        }
    }

    private JsonBody() {
    }

    public JsonBody put(String k, Object v){
        super.put(k, v);
        return this;
    }

    public static JsonBody custom(StatusCode code) {
        return custom(code, null);
    }

    public static JsonBody custom(StatusCode code, String msg){
        JsonBody body = new JsonBody();
        body.put("code", code.code());

        msg = msg == null ? code.msg() : msg;
        body.put("msg", msg);
        return body;
    }

    public static JsonBody ok(String msg) {
        return custom(StatusCode.SUCCESS, msg);
    }

    public static JsonBody ok(){
        return custom(StatusCode.SUCCESS);
    }

    public static JsonBody error() { return custom(StatusCode.ERROR); }

    public static JsonBody error(String msg) { return custom(StatusCode.ERROR, msg); }

    public StatusCode code() {
        return StatusCode.valueOf((int) this.getOrDefault("code", StatusCode.UNKNOWN_CODE.code()));
    }

    public String msg() {
        return (String) this.getOrDefault("msg", null);
    }

    public static JsonBody toJsonBody(String json) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return new JsonBody(mapper.readValue(json, new TypeReference<>() {
            }));
        } catch (JsonParseException e) {
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public String toJsonString() {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(this);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
        }
    }
}
